using AuthService.Domain.Entities;

namespace AuthService.Domain.Repositories;

/// <summary>
/// 用户仓储接口
/// 定义用户数据访问的抽象方法
/// </summary>
public interface IUserRepository
{
    /// <summary>
    /// 根据ID获取用户
    /// </summary>
    /// <param name="id">用户ID</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>用户实体或null</returns>
    Task<User?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default);

    /// <summary>
    /// 根据用户名获取用户
    /// </summary>
    /// <param name="username">用户名</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>用户实体或null</returns>
    Task<User?> GetByUsernameAsync(string username, CancellationToken cancellationToken = default);

    /// <summary>
    /// 根据邮箱获取用户
    /// </summary>
    /// <param name="email">邮箱地址</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>用户实体或null</returns>
    Task<User?> GetByEmailAsync(string email, CancellationToken cancellationToken = default);

    /// <summary>
    /// 检查用户名是否已存在
    /// </summary>
    /// <param name="username">用户名</param>
    /// <param name="excludeUserId">排除的用户ID（用于更新时检查）</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>是否存在</returns>
    Task<bool> ExistsByUsernameAsync(string username, Guid? excludeUserId = null, CancellationToken cancellationToken = default);

    /// <summary>
    /// 检查邮箱是否已存在
    /// </summary>
    /// <param name="email">邮箱地址</param>
    /// <param name="excludeUserId">排除的用户ID（用于更新时检查）</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>是否存在</returns>
    Task<bool> ExistsByEmailAsync(string email, Guid? excludeUserId = null, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取用户列表（分页）
    /// </summary>
    /// <param name="pageNumber">页码（从1开始）</param>
    /// <param name="pageSize">每页大小</param>
    /// <param name="searchTerm">搜索关键词（可选）</param>
    /// <param name="tenantId">租户ID（可选）</param>
    /// <param name="isActive">是否激活（可选）</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>用户列表和总数</returns>
    Task<(IEnumerable<User> Users, int TotalCount)> GetPagedAsync(
        int pageNumber = 1,
        int pageSize = 20,
        string? searchTerm = null,
        string? tenantId = null,
        bool? isActive = null,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// 根据角色获取用户列表
    /// </summary>
    /// <param name="role">角色名称</param>
    /// <param name="tenantId">租户ID（可选）</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>用户列表</returns>
    Task<IEnumerable<User>> GetByRoleAsync(string role, string? tenantId = null, CancellationToken cancellationToken = default);

    /// <summary>
    /// 根据权限获取用户列表
    /// </summary>
    /// <param name="permission">权限名称</param>
    /// <param name="tenantId">租户ID（可选）</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>用户列表</returns>
    Task<IEnumerable<User>> GetByPermissionAsync(string permission, string? tenantId = null, CancellationToken cancellationToken = default);

    /// <summary>
    /// 创建用户
    /// </summary>
    /// <param name="user">用户实体</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>创建的用户实体</returns>
    Task<User> CreateAsync(User user, CancellationToken cancellationToken = default);

    /// <summary>
    /// 更新用户
    /// </summary>
    /// <param name="user">用户实体</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>更新的用户实体</returns>
    Task<User> UpdateAsync(User user, CancellationToken cancellationToken = default);

    /// <summary>
    /// 删除用户（软删除）
    /// </summary>
    /// <param name="id">用户ID</param>
    /// <param name="deletedBy">删除者</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>是否成功</returns>
    Task<bool> DeleteAsync(Guid id, string? deletedBy = null, CancellationToken cancellationToken = default);

    /// <summary>
    /// 物理删除用户
    /// </summary>
    /// <param name="id">用户ID</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>是否成功</returns>
    Task<bool> HardDeleteAsync(Guid id, CancellationToken cancellationToken = default);

    /// <summary>
    /// 批量创建用户
    /// </summary>
    /// <param name="users">用户列表</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>创建的用户列表</returns>
    Task<IEnumerable<User>> CreateBatchAsync(IEnumerable<User> users, CancellationToken cancellationToken = default);

    /// <summary>
    /// 批量更新用户
    /// </summary>
    /// <param name="users">用户列表</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>更新的用户列表</returns>
    Task<IEnumerable<User>> UpdateBatchAsync(IEnumerable<User> users, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取用户统计信息
    /// </summary>
    /// <param name="tenantId">租户ID（可选）</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>统计信息</returns>
    Task<UserStatistics> GetStatisticsAsync(string? tenantId = null, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取最近登录的用户
    /// </summary>
    /// <param name="count">数量</param>
    /// <param name="tenantId">租户ID（可选）</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>用户列表</returns>
    Task<IEnumerable<User>> GetRecentlyLoggedInAsync(int count = 10, string? tenantId = null, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取锁定的用户
    /// </summary>
    /// <param name="tenantId">租户ID（可选）</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>用户列表</returns>
    Task<IEnumerable<User>> GetLockedUsersAsync(string? tenantId = null, CancellationToken cancellationToken = default);

    /// <summary>
    /// 搜索用户
    /// </summary>
    /// <param name="keyword">搜索关键词</param>
    /// <param name="page">页码</param>
    /// <param name="size">每页大小</param>
    /// <param name="tenantId">租户ID（可选）</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>用户列表和总数</returns>
    Task<(IEnumerable<User> Users, int TotalCount)> SearchAsync(
        string keyword,
        int page = 1,
        int size = 10,
        string? tenantId = null,
        CancellationToken cancellationToken = default);
}

/// <summary>
/// 用户统计信息
/// </summary>
public class UserStatistics
{
    /// <summary>
    /// 总用户数
    /// </summary>
    public int TotalUsers { get; set; }

    /// <summary>
    /// 激活用户数
    /// </summary>
    public int ActiveUsers { get; set; }

    /// <summary>
    /// 锁定用户数
    /// </summary>
    public int LockedUsers { get; set; }

    /// <summary>
    /// 已验证邮箱用户数
    /// </summary>
    public int EmailVerifiedUsers { get; set; }

    /// <summary>
    /// 已验证手机用户数
    /// </summary>
    public int PhoneVerifiedUsers { get; set; }

    /// <summary>
    /// 今日新增用户数
    /// </summary>
    public int TodayNewUsers { get; set; }

    /// <summary>
    /// 本周新增用户数
    /// </summary>
    public int WeekNewUsers { get; set; }

    /// <summary>
    /// 本月新增用户数
    /// </summary>
    public int MonthNewUsers { get; set; }

    /// <summary>
    /// 最近30天活跃用户数
    /// </summary>
    public int ActiveUsersLast30Days { get; set; }
}
